package com.peng.herostory.rank;

import com.alibaba.fastjson.JSONObject;
import com.peng.herostory.async.AsyncThreadProcessor;
import com.peng.herostory.async.IAsyncOperation;
import com.peng.herostory.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;

@Slf4j
public final class RankService {

    private static final RankService instance = new RankService();

    private RankService() {

    }

    public static RankService getInstance() {
        return instance;
    }

    public void getRank(Consumer<List<RankItem>> callback) {
        AsyncThreadProcessor.getInstance().process(new GetRankOp(callback));

    }

    /**
     * 更新redis中的用户排行榜情况
     *
     * @param winnerId
     * @param loserId
     */
    public void refreshRankInRedis(Integer winnerId, int loserId) {

        try (Jedis jedis = RedisUtil.getRedis()) {
            Long newWin = jedis.hincrBy("User_" + winnerId, "Win", 1);
            jedis.hincrBy("User_" + loserId, "Lose", 1);
            jedis.zadd("Rank", newWin, String.valueOf(winnerId));
        } catch (Exception e) {
            log.error("e:{0}", e);
        }

    }

    private class GetRankOp implements IAsyncOperation {

        private Consumer<List<RankItem>> callback;
        private List<RankItem> rankItemList = new ArrayList<>();

        public GetRankOp(Consumer<List<RankItem>> callback) {

            this.callback = callback;
        }

        @Override
        public void doAsync() {
            try (Jedis jedis = RedisUtil.getRedis()) {
                Set<Tuple> rankList = jedis.zrevrangeWithScores("Rank", 0, 9);
                log.info("rankList:{}", rankList);
                if (rankList == null) {
                    return;
                }
                int rankId = 0;
                for (Tuple tuple : rankList) {
                    String userId = tuple.getElement();
                    double score = tuple.getScore();
                    String basicInfo = jedis.hget("User_" + userId, "BasicInfo");

                    if (StringUtils.isBlank(basicInfo)) {
                        log.info("basicInfo为空，userId为：{}", userId);
                        return;
                    }

                    JSONObject jsonObject = JSONObject.parseObject(basicInfo);

                    RankItem rankItem = new RankItem();
                    rankItem.heroAvatar = jsonObject.getString("heroAvatar");
                    rankItem.userId = Integer.parseInt(userId);
                    rankItem.userName = jsonObject.getString("userName");
                    rankItem.win = (int) score;
                    rankItem.rankId = ++rankId;
                    rankItemList.add(rankItem);
                }


            } catch (Exception ex) {
                log.error("e:{1}", ex);
            }

        }

        @Override
        public void doFinish() {
            callback.accept(rankItemList);
        }
    }
}
